import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core'
import { ACLService, ACLType } from '@delon/acl'

import { IBaseInfoColumn, HoverType } from '@shared/interfaces/baseInfo'
import { PageService } from '@shared/services/page.service'

@Component({
  selector: 'app-info-row',
  templateUrl: './info-row.component.html',
  styleUrls: ['./info-row.component.less'],
})
export class InfoRowComponent implements OnInit {
  constructor(
    private aclService: ACLService,
    private pageService: PageService,
  ) {}

  @Input() height = '100'
  @Input() columns: Array<IBaseInfoColumn>
  @Input() ifEdit: boolean
  @Output() active = new EventEmitter()
  // Use rowIndex to identify which which row is clicked
  @Input() rowIndex = 0

  showPopoverIndex = ''

  ngOnInit() {
    this.pageService.isBaseEdit$.subscribe(isEdit => {
      if (isEdit) {
        this.preCheckValid()
      }
    })
    this.resetComputeSpanForEachColumn()
  }

  /** 进入编辑立刻校验一遍，因为后端数据也不可信 */
  preCheckValid(): void {
    this.columns.forEach(column => {
      if (!column.validator) return
      const validator = column.validator
      const val = column.value
      column.validator.currentErrorTip = ''
      for (let i = 0; i < validator.funcs.length; i++) {
        if (!validator.funcs[i](val)) {
          column.validator.currentErrorTip = validator.errorTips[i]
          break
        }
      }

      if (column.validator.currentErrorTip.length > 0) {
        column.hover = HoverType.Error
        column.validator.isError = true
      }
    })
  }

  hoverClassName(column: IBaseInfoColumn): string {
    if (!column.disEditable && column.hover === HoverType.Error) {
      return 'error'
    }

    if (!column.disEditable && column.hover === HoverType.Active) {
      return 'hover'
    }

    return ''
  }

  editClassName(column: IBaseInfoColumn): string {
    if (!column.disEditable && column.hover === HoverType.Error) {
      return 'errorEditable'
    }

    if (!column.disEditable && column.hover === HoverType.Active) {
      return 'editable'
    }

    return ''
  }

  activeItem(columnId: number, column: IBaseInfoColumn) {
    if (columnId === undefined || column.disEditable) {
      return
    }
    this.active.emit(columnId)
  }

  validate(val: any, errorPopover: HTMLElement, column: IBaseInfoColumn): void {
    if (!column.validator) {
      return
    }

    const validator = column.validator
    column.validator.currentErrorTip = ''
    for (let i = 0; i < validator.funcs.length; i++) {
      if (!validator.funcs[i](val)) {
        column.validator.currentErrorTip = validator.errorTips[i]
        break
      }
    }

    if (column.validator.currentErrorTip.length > 0) {
      column.hover = HoverType.Error
      column.validator.isError = true
    } else {
      column.hover = HoverType.Active
      column.validator.isError = false
    }

    if (column.validator.isError) {
      this.showPopoverIndex = column.index
      errorPopover.click()
    } else {
      this.showPopoverIndex = ''
    }

  }

  clickHandler(errorPopover: HTMLElement, column: IBaseInfoColumn): void {
    if (column.validator) {
      if (column.validator.isError) {
        this.showPopoverIndex = column.index
        errorPopover.click()
      }
    }
  }

  canAbility(column: IBaseInfoColumn): ACLType {
    const { acl, aclMode } = column
    if (!acl) {
      return null
    }

    return {
      ability: acl,
      mode: aclMode || 'oneOf',
    }
  }

  getLabelClass(diff: boolean): string {
    return diff ? 'cil__label diff' : 'cil__label'
  }

  getValueClass(diff: boolean): string {
    return diff ? 'cil__value diff' : 'cil__value'
  }

  getIsNewTag(diff: boolean): string {
    return diff ? '(新)' : ''
  }

  /** 检查值是否直接展示 */
  checkValueIsDisplayDirectly(str: string): boolean {
    return str !== undefined && str !== null && str !== ''
  }

  private resetComputeSpanForEachColumn(): void {
    if (!this.columns) {
      return
    }

    const totalSize = this.columns.length
    const aclColumns = this.columns
      .filter(col => !!col.acl && !this.aclService.canAbility(this.canAbility(col)))

    const aclSize = aclColumns.length
    if (aclSize && aclSize < totalSize) {
      const spanSize = aclColumns.map(col => col.span).reduce((a: number, b: number) => a + b)

      const perSpan = Math.floor(spanSize / (totalSize - aclSize))

      let totalSpan = 0
      this.columns = this.columns.slice(0)
      .filter(col => !col.acl || this.aclService.canAbility({ ability: col.acl }))
      .map((col, idx, arr) => {
        col.span += perSpan
        totalSpan += col.span
        if (idx === arr.length - 1) {
          col.span += (24 - totalSpan)
        }
        return col
      })
    }
  }

  // 提示框变化
  popoverChange(flag: boolean): void {
    if (!flag) {
      this.showPopoverIndex = ''
    }
  }
}
